#pragma once
#include <zGraphicsConfig.hpp>
#include <common.hpp>
#include "../Graphics/Graphics.hpp"
#include "../Resource/Texture/Texture.hpp"

namespace zzz {
class ZGRAPHICS_CLASS FBO {
public:
  FBO();
  virtual ~FBO();

  GLuint GetID();
  void Bind();
  void Unbind();

  void AttachTexture(Texture &tex,
                      GLenum attachment = GL_COLOR_ATTACHMENT0_EXT,
                      int mipLevel      = 0,
                      int zSlice        = 0);

  virtual void AttachTexture(GLenum texTarget,
                              GLuint texId,
                              GLenum attachment = GL_COLOR_ATTACHMENT0_EXT,
                              int mipLevel      = 0,
                              int zSlice        = 0);

  virtual void AttachTextures(int numTextures,
                               GLenum texTarget[],
                               GLuint texId[],
                               GLenum attachment[] = NULL,
                               int mipLevel[]      = NULL,
                               int zSlice[]        = NULL);

  virtual void AttachRenderBuffer(GLuint buffId,
                                   GLenum attachment = GL_COLOR_ATTACHMENT0_EXT);

  virtual void AttachRenderBuffers(int numBuffers, GLuint buffId[],
                                    GLenum attachment[] = NULL);

  void Unattach(GLenum attachment);

  void UnattachAll();

  bool CheckStatus();
  bool IsValid();

  /// Is attached type GL_RENDERBUFFER or GL_TEXTURE?
  GLenum GetAttachedType(GLenum attachment);

  /// What is the Id of Renderbuffer/texture currently
  /// attached to "attachement?"
  GLuint GetAttachedId(GLenum attachment);

  /// Which mipmap level is currently attached to "attachement?"
  GLint  GetAttachedMipLevel(GLenum attachment);

  /// Which cube face is currently attached to "attachment?"
  GLint  GetAttachedCubeFace(GLenum attachment);

  /// Which z-slice is currently attached to "attachment?"
  GLint  GetAttachedZSlice(GLenum attachment);


  static int GetMaxColorAttachments();
  static void Disable();

private:
  GLuint fbo_;
};

};  // namespace zzz